/*
 * Copyright (c) 2011-2015. ShenZhen trendit Information Technology Co.,Ltd.
 *
 * All right reserved.
 *
 * This software is the confidential and proprietary
 * information of trendit Company of China.
 * ("Confidential Information"). You shall not disclose
 * such Confidential Information and shall use it only
 * in accordance with the terms of the contract agreement
 * you entered into with trendit inc.
 */

package com.trendit.classicpos.util;

import android.text.TextUtils;

import java.io.UnsupportedEncodingException;

public class ByteUtils {

    public static int byte2ToInt(byte[] byte2) {
        int ret = 0;
        ret += (byte2[2] & 0xff) << 8;
        ret += (byte2[3] & 0xff);

        return ret;
    }

    public static int byte4ToInt(byte[] byte4) {
        int ret = 0;
        ret += (byte4[0] & 0xff) << 24;
        ret += (byte4[1] & 0xff) << 16;
        ret += (byte4[2] & 0xff) << 8;
        ret += (byte4[3] & 0xff);

        return ret;
    }

    /**
     * 字符串转换为ASCII码表示的Byte数组
     * 方法名：string2ASCIIByteArray
     * 描 述：
     *
     * @param str
     * @return byte[] 日 期：2014年10月13日 by lijinniu
     */
    public static byte[] string2ASCIIByteArray(String str) {
        if (TextUtils.isEmpty(str)) {
            return null;
        }
        byte[] data = null;
        try {
            data = str.getBytes("US-ASCII");
        } catch (UnsupportedEncodingException e) {

            android.util.Log.e("xgd", "字符串转换为ASCII码Byte数组错误");
            e.printStackTrace();
        }
        return data;
    }

    /**
     * ASCII码byte数组转为字符串
     * 方法名：byteArray2String
     * 描 述：aaa
     *
     * @param data
     * @return String 日 期：2014年10月13日 by lijinniu
     */
    public static String asciiByteArray2String(byte[] data) {
        if (data == null) {
            return "";
        }
        StringBuffer tStringBuf = new StringBuffer();
        char[] tChars = new char[data.length];

        int end = 0;
        for (int i = 0; i < data.length; i++) {
            /*if (data[i] == 0x20) {
                end = i;
                break; // 卡号最后可能含有空格，去除空格
            } else {
                end = data.length;
            }*/
            end = data.length;
            tChars[i] = (char) data[i];
        }

        tStringBuf.append(tChars, 0, end);

        return tStringBuf.toString().trim();
    }


    /**
     * hex string convert to byte[]
     */
    public static byte[] hexString2ByteArray(String hexStr) {
        if (hexStr == null) {
            return null;
        }

        if (hexStr.length() % 2 != 0) {
            return null;
        }
        byte[] data = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            char hc = hexStr.charAt(2 * i);
            char lc = hexStr.charAt(2 * i + 1);
            byte hb = hexChar2Byte(hc);
            byte lb = hexChar2Byte(lc);

            if (hb < 0 || lb < 0) {
                return null;
            }

            int n = hb << 4;
            data[i] = (byte) (n + lb);
        }

        return data;
    }

    public static short[] stringToShortArray(String randNo) {
        char[] cc = new char[randNo.length()];
        short[] shorts = new short[randNo.length()];
        randNo.getChars(0, randNo.length(), cc, 0);

        for (int i = 0; i < cc.length; ++i) {
            shorts[i] = (short) cc[i];
        }

        return shorts;
    }

    public static byte hexChar2Byte(char c) {
        if (c >= '0' && c <= '9') {
            return (byte) (c - '0');
        } else if (c >= 'a' && c <= 'f') {
            return (byte) (c - 'a' + 10);
        } else if (c >= 'A' && c <= 'F') {
            return (byte) (c - 'A' + 10);
        } else {
            return -1;
        }
    }

    public static int HexBytes2Int(byte[] data) {
        String str = byteArray2HexString(data);
        return Integer.parseInt(str, 16);
    }

    /**
     * byte[] convert to hex string
     */
    public static String byteArray2HexString(byte[] arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }

        StringBuilder sbd = new StringBuilder();
        for (byte b : arr) {
            String tmp = Integer.toHexString(0xFF & b);
            if (tmp.length() < 2) {
                tmp = "0" + tmp;
            }

            sbd.append(tmp);
        }

        return sbd.toString();
    }

    public static String bcd2Ascii(String bcd) {
        if (TextUtils.isEmpty(bcd)) {
            return null;
        }
        char[] bcdChars = bcd.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (char c : bcdChars) {
            String hex = Integer.toHexString(c);
            sb.append(hex);
        }
        return sb.toString();
    }

    public static String byteArray2HexStringWithSpace(byte[] arr) {
        StringBuilder sbd = new StringBuilder();
        for (byte b : arr) {
            String tmp = Integer.toHexString(0xFF & b);
            if (tmp.length() < 2) {
                tmp = "0" + tmp;
            }

            sbd.append(tmp);
            sbd.append("  ");
        }

        return sbd.toString();
    }

    /**
     * short转byte数组，高位在前
     * 方法名：short2ByteArrayHigh
     *
     * @param arr
     * @return 日   期：2014年10月28日 by lijinniu
     */
    public static byte[] short2ByteArrayHigh(short arr) {
        byte[] sbd = new byte[2];
        sbd[0] = (byte) (arr / 256);
        sbd[1] = (byte) (0xFF & arr);
        return sbd;
    }

    public static String getBCDString(byte[] data, int start, int end) {
        byte[] t = new byte[end - start + 1];
        System.arraycopy(data, start, t, 0, t.length);
        return ByteUtils.byteArray2HexString(t);
    }

    public static String getHexString(byte[] data, int start, int end) {
        byte[] t = new byte[end - start + 1];
        System.arraycopy(data, start, t, 0, t.length);
        return ByteUtils.byteArray2HexStringWithSpace(t);
    }

    public static String toHex(Integer i) {
        return Integer.toHexString((i & 0x000000ff) | 0xffffff00)
                .substring(6).toUpperCase();
    }

    //Bcd short for Binary-coded decimal
    public static byte[] str2Bcd(String str) {
        if (str == null) {
            return null;
        }
        int len = str.length();
        if (len % 2 != 0) {
            str = "0" + str;
            len = str.length();
        }

        byte[] strBytes = new byte[len];
        if (len >= 2) {
            len = len / 2;
        }

        byte[] bcd = new byte[len];
        strBytes = str.getBytes();
        int j, k;

        for (int p = 0; p < str.length() / 2; p++) {
            if ((strBytes[2 * p] >= '0') && (strBytes[2 * p] <= '9')) {
                j = strBytes[2 * p] - '0';
            } else if ((strBytes[2 * p] >= 'a') && (strBytes[2 * p] <= 'z')) {
                j = strBytes[2 * p] - 'a' + 0x0a;
            } else {
                j = strBytes[2 * p] - 'A' + 0x0a;
            }

            if ((strBytes[2 * p + 1] >= '0') && (strBytes[2 * p + 1] <= '9')) {
                k = strBytes[2 * p + 1] - '0';
            } else if ((strBytes[2 * p + 1] >= 'a') && (strBytes[2 * p + 1] <= 'z')) {
                k = strBytes[2 * p + 1] - 'a' + 0x0a;
            } else {
                k = strBytes[2 * p + 1] - 'A' + 0x0a;
            }

            int a = (j << 4) + k;
            byte b = (byte) a;
            bcd[p] = b;
        }

        return bcd;
    }

    /**
     * 将int数值转换为占四个字节的byte数组，本方法适用于(高位在前，低位在后)的顺序。 和bytesToInt（）配套使用
     *
     * @param value 要转换的int值
     * @return byte数组
     */
    public static byte[] intToBytes(int value) {
        byte[] src = new byte[4];
        src[0] = (byte) ((value >> 24) & 0xFF);
        src[1] = (byte) ((value >> 16) & 0xFF);
        src[2] = (byte) ((value >> 8) & 0xFF);
        src[3] = (byte) (value & 0xFF);
        return src;
    }

    public static byte[] intTo2Bytes(int len) {
        byte[] lens = new byte[2];
        lens[0] = (byte) (len >> 8);
        lens[1] = (byte) (len & 0xFF);
        return lens;
    }

    public static byte[] intTo4Bytes(int len) {
        byte[] b = new byte[4];
        b[0] = (byte) ((len >> 24) & 0xFF);
        b[1] = (byte) ((len >> 16) & 0xFF);
        b[2] = (byte) ((len >> 8) & 0xFF);
        b[3] = (byte) (len & 0xFF);
        return b;
    }

    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }

    public static byte[] byteTo1Bytes(byte value) {
        byte[] b = new byte[1];
        b[0] = value;
        return b;
    }

    public static byte[] createBytes(byte[]... bytes) {
        int dataLen = 0;
        for (byte[] b : bytes) {
            if (b == null) {
                continue;
            }
            dataLen = dataLen + b.length;
        }
        byte[] data = new byte[dataLen];
        int tmpDataLen = 0;
        for (byte[] b : bytes) {
            if (b == null) {
                continue;
            }
            System.arraycopy(b, 0, data, tmpDataLen, b.length);
            tmpDataLen = tmpDataLen + b.length;
        }
        return data;
    }

    public static byte[] byteToBinary(byte value) {
        byte[] bits = new byte[8];
        for (int i = 0; i < bits.length; i++) {
            bits[7 - i] = (byte) ((value >> i) & 0x01);
        }
        return bits;
    }
}
